import time
from pref import prefs
from pyo import *
import OscServer
from getScripts import finalDict as modulesDict
print modulesDict
from AudioFx import AudioSlot

# from AudioFx import modulesDict
# import slotScripts.getAllSlots
# print slotScripts.getAllSlots.alls
# OscServer.addCtrlr("lemur1", 8000,7999,8, "192.168.2.17")#"169.254.126.129"

class EmptyFx(AudioSlot):
    """
    example audio process
    """
    name = "Empty"
    ctrls = ["None","None","None"]
    def __init__(self):
        AudioSlot.__init__(self, "fx",self.name,self.ctrls)
        self.output = self.input

class EmptyMod(AudioSlot):
    """
    example audio process
    """
    name = "Empty"
    ctrls = ["None","None","None"]
    def __init__(self):
        AudioSlot.__init__(self, "mod",self.name,self.ctrls)

class OscClass(object):
    """
    parent class for Osc com, 6 sliders, 4 menus, 3 texts, 4 onoff buttons
    
    looks for mod in dict at global level, send index names to lemur for menu selection 
    and choose audio stream in dict acording to selection

    ? init selection ?

    args : 
        addressPrepend: name prepended to osc adresses (for object with lemur container)
        name: 


    """
    def __init__(self, addressPrepend, modulation,type):
        self.type = type 
        self.addressPrepend = addressPrepend
        self.osc = OscServer.OscCtrls(addressPrepend)
        self.allModules = modulesDict
        self.modules = modulesDict[type] # keeping dict here to load effects # to change dict
        self.modulation = modulation # dict with other module's mods 
        # audio
        self.audioIn = Sig([0 for i in range(prefs["channels"])]) #next version audio dict like modulation
        # self.modIn = [Sig(0) for i in range(3)] # get from modu lation dict
        self.modInChoo = [Sig(0) for i in range(3)] # get from modu lation dict
        self.audioOut = Sig([0 for i in range(prefs["channels"])])
        self.modOut = Sig(0)

        # self.slot = self.modules[0]["class"]() # keep main slot variable to load fx and mod
        self.slot = EmptyFx()
        self.slotMute = 1

        # // OSC Controls
        self.ctrl1 = self.osc.newAudio("ctrl1",[0],"/audio","/ctrl1/x","lemur1",[0])
        self.ctrl2 = self.osc.newAudio("ctrl2",[1],"/audio","/ctrl2/x","lemur1",[0])
        self.ctrl3 = self.osc.newAudio("ctrl3",[2],"/audio","/ctrl3/x","lemur1",[0])
        self.modAmnt1 = 2*self.osc.newAudio("modAmnt1",[3],"/audio","/modamount1/x","lemur1",[0.5])-1
        self.modAmnt2 = 2*self.osc.newAudio("modAmnt2",[4],"/audio","/modamount2/x","lemur1",[0.5])-1
        self.modAmnt3 = 2*self.osc.newAudio("modAmnt3",[5],"/audio","/modamount3/x","lemur1",[0.5])-1
        self.osc.newData("menuSelectionMain","i",self.oscSlotSel, "/slotselect/selection", "/slotselect/selection", "lemur1")
        self.osc.newData("groupSelect","i",self.groupSel, "/groupSelect/selection", "/groupSelect/selection", "lemur1")
        self.osc.newData("modsel1","i",self.modsel1, "/modselect1/selection", "/modselect1/selection", "lemur1")
        self.osc.newData("modsel2","i",self.modsel2, "/modselect2/selection", "/modselect2/selection", "lemur1")
        self.osc.newData("modsel3","i",self.modsel3, "/modselect3/selection", "/modselect3/selection", "lemur1")
        self.osc.newData("globalOnOff","i",self.globalOnOff, "/globalOnOff/x", "/globalOnOff/x", "lemur1")
        self.osc.newData("enableMod1","i",self.enableMod1, "/enableMod1/x", "/enableMod1/x", "lemur1")
        self.osc.newData("enableMod2","i",self.enableMod2, "/enableMod2/x", "/enableMod2/x", "lemur1")
        self.osc.newData("enableMod3","i",self.enableMod3, "/enableMod3/x", "/enableMod3/x", "lemur1")
        self.osc.newDataOut("fillSlotMenu", "s"*len(self.modules), "/slotselect/setSelection", "lemur1")
        self.osc.newDataOut("fillGroupMenu", "s"*len(self.modules), "/GroupSelect/setSelection", "lemur1")
        self.osc.newDataOut("fillMods", "s"*len(self.modulation), "/setMods", "lemur1")
        self.osc.newDataOut("ctrlNames", "ssss", "/setCtrlNames", "lemur1")

        self.mctrl1 = Clip(self.ctrl1+(Abs((self.modAmnt1>0)-self.ctrl1)*self.modAmnt1*self.modInChoo[0]),0,1)
        self.mctrl2 = Clip(self.ctrl2+(Abs((self.modAmnt2>0)-self.ctrl2)*self.modAmnt2*self.modInChoo[1]),0,1)
        self.mctrl3 = Clip(self.ctrl3+(Abs((self.modAmnt3>0)-self.ctrl3)*self.modAmnt3*self.modInChoo[2]),0,1)
        # // INITOSC

        self.oscInitCtrls() # initialise interface
        self.oscSendModuleNames()
        self.oscSendModulationNames()
        self.osc.send("ctrlNames",["None","None","None","Empty"])
        self.oscSlotSel(0)
        time.sleep(0.1)
        # \\ INITOSC
        # \\ OSC Controls


    def getMod(self):
        if self.slot.type == "mod":
            return self.modOut

    def getAudio(self):
        return self.audioOut
    

    def setAudio(self, audio):
        self.audioIn.setValue(audio)

    #/// OSC Receive Functions
    def groupSel(self, selected):
        # save group selected and send names of group
        pass

    def oscSlotSel(self, selected):
        # function inits class into slot from modules dict
        # sets audio inputs and modulation in
        # sets audio controls (modulation+Ctrl)
        # gets audio output and mod out(to modout dict/classes'smodout variable>modoutdict)
        # when modules changes
        # put sig(0) into inputs (audio and mod)
        # 
        # _DONE_ init class from dict into slot variable
        # _DONE_  send control names to lemur
        # _DONE_ connect audio or mods (if) inouts
        # _ (audio init stuff: mute fx?, fadein?)

        # deconnect audio from last module?
        self.slot = self.modules[int(selected)]["class"]()

        if self.slot.type == "fx":
            self.slot.setAudioIn(self.audioIn)
            if self.slotMute:
                self.audioOut.setValue(self.slot.getAudioOut())

        else:
            self.modOut.setValue(self.slot.getMod())
        # here get init value and send to 

        initvals = self.slot.getInitVals()
        for i in range(3):
            self.osc.send("ctrl%i" % (i+1),initvals[i])

        names = self.slot.getAllInfo()
        self.osc.send("ctrlNames",names)
        self.slot.setCtrls([self.mctrl1,self.mctrl2,self.mctrl3])

    ### def modsel(self, selected, which):
    ###     if selected:
    ###         self.modInChoo[which].set...
    ### Meme chose, une seule methode...
    def modsel1(self, selected):
        if selected:
            self.modInChoo[0].setValue(self.modulation[int(selected)]["audio"])
        else:
            self.modInChoo[0].setValue(Sig(0))

    def modsel2(self, selected):
        if selected:
            self.modInChoo[1].setValue(self.modulation[int(selected)]["audio"])
        else:
            self.modInChoo[1].setValue(Sig(0))

    def modsel3(self, selected):
        if selected:
            self.modInChoo[2].setValue(self.modulation[int(selected)]["audio"])
        else:
            self.modInChoo[2].setValue(Sig(0))
#\\\ OSC Receive Functions

    def enableMod1(self, onoff):
        self.modInChoo[0].setMul(onoff)
    
    def enableMod2(self, onoff):
        self.modInChoo[1].setMul(onoff)
            
    def enableMod3(self, onoff):
        self.modInChoo[2].setMul(onoff)
        
    def globalOnOff(self, onoff):
        self.slotMute = onoff
        if onoff:
            self.slot.turnOn()
            if self.slot.type == "fx":
                self.audioOut.setValue(self.slot.getAudioOut())
            elif self.slot.type == "mod":
                self.modOut.setValue(self.slot.getMod())
        else:
            self.slot.turnOff()
            if self.slot.type == "fx":
                self.audioOut.setValue(self.audioIn)
            elif self.slot.type == "mod":
                self.modOut.setValue(Sig(0))

    #// good to go functions
    def oscSendModuleNames(self):#names of possible slots to load, available at init. 2 lists for mod and fx
        self.osc.send("fillSlotMenu",[self.modules[i]["name"] for i in range(len(self.modules))])

    def oscSendModulationNames(self):
        self.osc.send("fillMods",[self.modulation[i]["name"] for i in range(len(self.modulation))])

    def oscInitCtrls(self):
        self.osc.send("ctrl1",[0])
        self.osc.send("ctrl2",[0])
        self.osc.send("ctrl3",[0])
        self.osc.send("modAmnt1",[0.5])
        self.osc.send("modAmnt2",[0.5])
        self.osc.send("modAmnt3",[0.5])
        self.osc.send("globalOnOff",[1])
        self.osc.send("enableMod1",[1])
        self.osc.send("enableMod2",[1])
        self.osc.send("enableMod3",[1])
        self.osc.send("menuSelectionMain", 0)
        self.osc.send("modsel1", 0)
        self.osc.send("modsel2", 0)
        self.osc.send("modsel3", 0)
